package com.sds.session.controller;

import java.util.List;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import com.sds.servlet.vo.HeaderVO;
import com.sds.session.manager.SessionMasterInfo;
import com.sds.session.manager.vo.Domain;
import com.sds.session.manager.vo.UserInfo;
import com.sds.session.service.IDPSessionService;

@Controller
public class SessionController {
	
	private Logger logger = LoggerFactory.getLogger(SessionController.class);
	
	@Autowired
	private SessionMasterInfo sessionMasterInfo;
	
	@Autowired
	private IDPSessionService idpSessionService;
	
	@ModelAttribute
	public HeaderVO headerVO(HttpServletRequest request, HttpServletResponse response) {
		HeaderVO headerVO = new HeaderVO();
		headerVO.setType("session");
		headerVO.setSessionId(request.getSession().getId());
		headerVO.setUserId(request.getParameter("userId"));
		return headerVO;
	}
	
	/**
	 * create Session Service provide Request from IDP
	 * @param headerVO
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	@RequestMapping("/session/createSession.do")
    public ModelAndView createSession(@ModelAttribute HeaderVO headerVO, HttpServletRequest request, HttpServletResponse response) throws Exception {
		
		HttpSession httpSession = request.getSession();
		
		String userId = request.getHeader("userId");
		String userIP = request.getHeader("userIP");
		
		httpSession.setAttribute("userId", userId);
		httpSession.setAttribute("userIP", userIP);
		
		logger.debug("############# SP createSession ##############");
		logger.debug("User ID : " + userId);
		logger.debug("User IP : " + userIP);
		logger.debug("Session ID : " + httpSession.getId());
		logger.debug("#############################################");

		return null;
    }
	
	/**
	 * check Session Service provide Request from IDP
	 * @param headerVO
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	@RequestMapping("/session/checkSession.do")
    public ModelAndView checkSession(@ModelAttribute HeaderVO headerVO, HttpServletRequest request, HttpServletResponse response) throws Exception {
		
		HttpSession httpSession = request.getSession();
		
		String userId = request.getHeader("userId");
		String userIP = request.getHeader("userIP");
		
		String sessionUserId = (String) httpSession.getAttribute("userId");
		String sessionUserIP = (String) httpSession.getAttribute("userIP");
		
		if( userId!=null && userId.equals(sessionUserId)
				&& userIP!=null && userIP.equals(sessionUserIP) ) {
			response.setHeader("CheckResult", "true");
		}
		else {
			response.setHeader("CheckResult", "false");
		}
		
		logger.debug("############## SP checkSession ##############");
		logger.debug("User ID : " + userId);
		logger.debug("User IP : " + userIP);
		logger.debug("Session ID : " + httpSession.getId());
		logger.debug("#############################################");
		
		return null;
    }
	
	/**
	 * create Session Service provide Request from Client
	 * @param headerVO
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	@RequestMapping("/session/idp/createIDPSession.do")
    public ModelAndView createIDPSession(@ModelAttribute HeaderVO headerVO, HttpServletRequest request, HttpServletResponse response) throws Exception {
		String userId = request.getHeader("userId");
		String userIP = request.getHeader("userIP");
		String domain = request.getHeader("domain");
		
		UserInfo userInfo = sessionMasterInfo.getUserInfo(userId, userIP);
		
		if(userInfo!=null) {
			if(!userInfo.isRegisteredDomain(domain)) {
				Cookie[] cookie = idpSessionService.createSession(domain, userId, userIP);
				userInfo.addDomain(domain, cookie);
			}
		} else {
			Cookie[] cookie = idpSessionService.createSession(domain, userId, userIP);
			sessionMasterInfo.setUserInfo(userId, userIP, cookie, domain);
		}
		
		userInfo = sessionMasterInfo.getUserInfo(userId,userIP);
		logger.debug("########### IDP createIDPSession #############");
		userInfo.debug();
		logger.debug("##############################################");

		return null;
    }
	
	/**
	 * check Session Service provide Request from Client
	 * @param headerVO
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	@RequestMapping("/session/idp/checkIDPSession.do")
    public ModelAndView checkIDPSession(@ModelAttribute HeaderVO headerVO, HttpServletRequest request, HttpServletResponse response) throws Exception {
		String userId = request.getHeader("userId");
		String userIP = request.getHeader("userIP");
		String newDomain = request.getHeader("domain");
		
		UserInfo userInfo = sessionMasterInfo.getUserInfo(userId,userIP);
		
		boolean checkSessionResult = false;
		
		if(userInfo!=null) {
			List<Domain> domains = userInfo.getDomains();
			for(Domain domain : domains) {
				checkSessionResult = idpSessionService.checkSession(domain.getName(),userId,userIP,domain.getCookie());
				if(checkSessionResult) break;
			}
		}
		
		if( checkSessionResult ) {
			response.setHeader("CheckResult", "true");
			if(!userInfo.isRegisteredDomain(newDomain)) {
				Cookie[] cookie = idpSessionService.createSession(newDomain, userId, userIP);
				userInfo.addDomain(newDomain, cookie);
			}
		}
		else {
			response.setHeader("CheckResult", "false");
		}

		if(userInfo!=null) {
			logger.debug("############ IDP checkIDPSession #############");
			userInfo.debug();
			logger.debug("##############################################");
		}

		return null;
    }
}